﻿// -----------------------------------------------------------------------
// <copyright file="ImageViewModelCustomBinder.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Website.CustomModelBinders
{
	#region Usings

	using System.Globalization;
	using System.IO;
	using System.Reflection;
	using System.Web;
	using System.Web.Mvc;

	using MBOP.Website.ViewModels.Common;

	#endregion

	/// <summary>
	/// ImageViewModel binder which assigns data from requests.
	/// </summary>
	public class ImageViewModelCustomBinder : DefaultModelBinder
	{
		#region Constants

		/// <summary>
		/// Represents the query string image id.
		/// </summary>
		private const string QUERY_STRING_IMAGE_ID_NAME = "Image.ID";

		/// <summary>
		/// Represents the image id property name.
		/// </summary>
		private const string PROPERTY_NAME_IMAGE_ID = "ID";

		/// <summary>
		/// Represents image name property name.
		/// </summary>
		private const string PROPERTY_NAME_IMAGE_NAME = "Name";

		/// <summary>
		/// Represents image url property name.
		/// </summary>
		private const string PROPERTY_NAME_IMAGE_URL = "Uri";

		/// <summary>
		/// Represents image content property name.
		/// </summary>
		private const string PROPERTY_NAME_IMAGE_CONTENT = "Content";

		/// <summary>
		/// Represents image content type property name.
		/// </summary>
		private const string PROPERTY_NAME_IMAGE_CONTENT_TYPE = "ContentType";

		#endregion

		#region Public Methods

		/// <summary>
		/// Assigns the request values and image view model.
		/// </summary>
		/// <param name="controllerContext">Controller context, which processing the current request.</param>
		/// <param name="bindingContext">Binding context, which contains values of the current request.</param>
		/// <returns>The image view model object representation.</returns>
		public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
		{
			object resultObj = new ImageViewModel();

			string imageName = string.Empty;

			ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(PROPERTY_NAME_IMAGE_CONTENT);

			HttpPostedFileBase file = null;

			if (valueResult != null)
			{
				file = valueResult.ConvertTo(typeof (HttpPostedFileBase), CultureInfo.InvariantCulture) as HttpPostedFileBase;
			}

			if (file != null)
			{
				this.SetImageContent(resultObj, file, bindingContext);
			}
			else if (bindingContext.ValueProvider.GetValue(PROPERTY_NAME_IMAGE_URL)!=null && !string.IsNullOrEmpty(bindingContext.ValueProvider.GetValue(PROPERTY_NAME_IMAGE_URL).AttemptedValue))
			{
				PropertyInfo nameProperty = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_NAME);

				string url = bindingContext.ValueProvider.GetValue(PROPERTY_NAME_IMAGE_URL).AttemptedValue;

				PropertyInfo urlProperty = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_URL);

				urlProperty.SetValue(resultObj, url, null);

				imageName = Path.GetFileName(url);

				nameProperty.SetValue(resultObj, imageName, null);
			}

			valueResult = bindingContext.ValueProvider.GetValue(QUERY_STRING_IMAGE_ID_NAME);

			if (valueResult != null)
			{
				PropertyInfo idPropertyInfo = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_ID);

				string idValue = !string.IsNullOrEmpty(valueResult.AttemptedValue) ? valueResult.AttemptedValue : null;

				idPropertyInfo.SetValue(resultObj,idValue,null);
			}


			return resultObj;
		}

		#region Private Methods

		/// <summary>
		/// Sets the image content for the object.
		/// </summary>
		/// <param name="resultObj">The result object.</param>
		/// <param name="file">The uploaded file.</param>
		/// <param name="bindingContext">Binding context, which contains values of the current request.</param>
		private void SetImageContent(object resultObj, HttpPostedFileBase file, ModelBindingContext bindingContext)
		{
			byte[] byteArray = new byte[file.ContentLength];

			file.InputStream.Read(byteArray, 0, file.ContentLength);

			PropertyInfo contentInfo = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_CONTENT);

			contentInfo.SetValue(resultObj, byteArray, null);

			PropertyInfo contentTypeProperty = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_CONTENT_TYPE);

			contentTypeProperty.SetValue(resultObj,file.ContentType,null);

			PropertyInfo imageNamePropertyInfo = bindingContext.ModelType.GetProperty(PROPERTY_NAME_IMAGE_NAME);

			imageNamePropertyInfo.SetValue(resultObj,file.FileName,null);
		}

		#endregion

		#endregion
	}
}